package com.youku.expression;

public abstract class BaseExpressionHandler implements ExpressionHandler {

	private final Position position;
	
	private final Interpreter interpreter;

	private final String openToken;

	private final String closeToken;

	public BaseExpressionHandler(Position position, String openToken, String closeToken,
			Interpreter interpreter) {
		this.position = position;
		this.interpreter = interpreter;
		this.openToken = openToken;
		this.closeToken = closeToken;
	}

	@Override
	public String parse(String text) {
		if (text == null || text.length() == 0) {
			return text;
		} else {
			return deepParse(text);
		}
	}

	private String deepParse(String text) {
		int offset = 0;
		int start = text.indexOf(openToken, offset);

		if (start == -1)
			return text;
		StringBuilder builder = new StringBuilder();
		char[] src = text.toCharArray();
		while (start > -1) {
			int end = text.indexOf(closeToken, start);
			if (end == -1) {
				builder.append(src, offset, src.length - offset);
				offset = src.length;
			} else {
				builder.append(src, offset, start - offset);
				offset = start + openToken.length();
				String content = new String(src, offset, end - offset);
				builder.append(handleToken(content));
				offset = end + closeToken.length();
			}
			start = text.indexOf(openToken, offset);
		}
		if (offset < src.length) {
			builder.append(src, offset, src.length - offset);
		}

		return deepParse(builder.toString());
	}
	// public String parse(String text) {
	// StringBuilder builder = new StringBuilder();
	// if (text != null && text.length() > 0) {
	// char[] src = text.toCharArray();
	// int offset = 0;
	// int start = text.indexOf(openToken, offset);
	// while (start > -1) {
	// if (start > 0 && src[start - 1] == '\\') {
	// // the variable is escaped. remove the backslash.
	// builder.append(src, offset, start - offset - 1).append(openToken);
	// offset = start + openToken.length();
	// } else {
	// int end = text.indexOf(closeToken, start);
	// if (end == -1) {
	// builder.append(src, offset, src.length - offset);
	// offset = src.length;
	// } else {
	// builder.append(src, offset, start - offset);
	// offset = start + openToken.length();
	// String content = new String(src, offset, end - offset);
	// builder.append(handleToken(content));
	// offset = end + closeToken.length();
	// }
	// }
	// start = text.indexOf(openToken, offset);
	// }
	// if (offset < src.length) {
	// builder.append(src, offset, src.length - offset);
	// }
	// }
	// return builder.toString();
	// }

	@Override
	public Object handleToken(String content) {
		return interpreter.interpreter(position, content);
	}

}
